<?php
@header('Content-Type: text/html; charset=utf-8');

define("TOKEN", "tanghn");
/*返回最大记录数*/
define("MAXRECORDS", 5);
define("URLROOT", "http://tanghn.xicp.net/");
define("SESSIONAGING", 600); /*unit: seconds*/

$g_helpmsg = "欢迎光临:)\n
本系统支持搜索、下单！

输入”?“或“帮助”: 打印帮助;
输入关键字：搜索菜单;
输入”菜单号“：添加到购物车;
输入“buy”或“购买”：下单；
输入“cancel”或“取消”：取消购买；

举例：
输入”辣的汉堡“：搜索;
输入”102“：放入购物车
输入“buy”：下单
try!
";

/*按微信格式组装消息，*/
function AssembleMenuMsg($lines_map, $from, $to){
	$counter = count($lines_map);
	$counter = ($counter>MAXRECORDS) ? MAXRECORDS : $counter;
	$time = time();
	
	$textTpl = sprintf(
"<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>%s</ArticleCount>
<Articles>
", $to, $from, $time, $counter);
	
	$i = 0;
	foreach ($lines_map as $line){
		if($i >= $counter)
		{
			break;
		}
		$id = $line['menuid'];

		$data = $id."：".$line['menuname']." ".$line['price']."元";
		
		$fullurl = URLROOT.$line['imageurl'];
		$textTpl = $textTpl.sprintf(
"<item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
", $data, $line['description'], $fullurl, "http://tanghn.xicp.net/row.php?openid=$to&menuid=$id");

		$i++;
	}

	$textTpl = $textTpl.
"</Articles>
</xml>";

	return $textTpl;
}

/*from-->to*/
function AssembleTextMsg($textMsg, $from, $to){
	$time = time();

	$textTpl = $textTpl.sprintf(
"<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>
", $to, $from, $time, $textMsg);
	
	return $textTpl;
}

/*lines_buy: 即购物车信息，比如101,2 102,3 105,8*/
/*appendInfo:需要追加的消息，可以填NULL*/
function AssembleCartMsg($lines_buy, $appendInfo, $from, $to){
	$time = time();
	$menu = GetFullMenu();
	$text = "您的订单：\n";
	$total = 0;
	
DEBUGINFO("Entry Assemble CartMsg:\r\n");
	$array = explode(" ", trim($lines_buy));
	foreach ($array as $index){
		$temp = explode(",", $index);
		$id = intval($temp[0],10);
		$counter = intval($temp[1],10);
		DEBUGINFO("id is ".$id.",counter is ".$counter."\r\n");
		
		$subtotal = $menu[$id]['price'] * $counter;
		$text = $text.$menu[$id]['menuname'].",".$counter."个: 小计：".$subtotal."元\n";
		$total += $subtotal;
	}
	$text = $text."\n合计：".$total."元\n";
	$text = $text.$appendInfo;
	
	$textTpl = $textTpl.sprintf(
"<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>
", $to, $from, $time, $text);
	
DEBUGINFO("Exit  Assemble CartMsg:\r\n");
	return $textTpl;
}

/*检查菜单号是否存在。输入：菜单号；返回：纪录数目*/
function CheckMenuId($menuNo){
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);
	mysql_query("set names utf8");

	$sqlstring = "SELECT * FROM kfcmenu where menuid=".$menuNo;
	$db_result = mysql_query($sqlstring);

	return mysql_num_rows($db_result);
}

/*未命中时打印默认菜单，考虑随机打印？？默认查询较慢需要优化？？*/
/*返回结果参考GetSearchMenu*/
function GetFullMenu(){
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);
	mysql_query("set names utf8");

	$temp = "SELECT * FROM kfcmenu";
	$db_result = mysql_query($temp);

	unset($lines_array);
	$lines_array = array();
	while($row = mysql_fetch_array($db_result))
	{
		$match_times = 0;
		$temp = array($row, $match_times);
		array_push($lines_array, $temp);
	}

	shuffle($lines_array); /*make random??*/
	
	for($i = 0; $i < count($lines_array); $i++){
		$row = $lines_array[$i][0];
		$map_result[$row['menuid']] = $row;
		/*$map_result[$row['name']] = $row;*/
	}
	mysql_close($con);
	return $map_result;
}

/*命中关键字时的结果，结果类型是array(menuid,menuname,price,keylist,description)，可以通过id索引*/
function GetSearchMenu($k){
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	$text = $k;
	$text = iconv("UTF-8", "GBK//IGNORE", $text);
	$text = urlencode($text);
	$result = file_get_contents("http://192.168.1.22:1985/?w=".$text);
	$result = iconv("GBK", "UTF-8//IGNORE", $result);

	DEBUGINFO("word segment result:".$result."\r\n");
	$fenci = explode(" ", $result);

	mysql_select_db("test", $con);
	mysql_query("set names utf8");

	$temp = "SELECT * FROM kfcmenu";
	$db_result = mysql_query($temp);

	unset($lines_array);
	$lines_array = array();
	while($row = mysql_fetch_array($db_result))
	{
		$match_times = 0;
		/*unset($lines_array); 清空变量*/

		foreach ($fenci as $current_keyword){
				if(eregi($current_keyword, $row['keylist']))  /*strstr不能匹配，不明原因。使用正则表达式*/
				/*if(false != stristr($current_keyword, $row['keylist']))*/
				{
					$match_times++;
				}
		}
		if($match_times>0){
			$temp = array($row, $match_times);
			array_push($lines_array, $temp);
		}else{
			continue;
		}
	}

	/*自定义比较*/
	usort($lines_array, 'compare');
	
	for($i = 0; $i < count($lines_array); $i++){
		$row = $lines_array[$i][0];
		$map_result[$row['menuid']] = $row;
		/*$map_result[$row['menuname']] = $row;*/
	}
	
	mysql_close($con);
	return $map_result;
}

function UpdateCart($inputStr, $vId, $num)
{
	DEBUGINFO("Entry UpdateCart, old cart str is ".$inputStr.", menu id is ".$vId.",num is ".$num."\r\n");
	
	if(NULL != $vId){
		$item = trim($inputStr);/*remove white character*/
		
		if(0 != strlen($item)){
			$item = explode(" ", $item);

			foreach ($item as $index){
				$temp = explode(",", $index);
				$id = intval($temp[0],10);
				$counter = intval($temp[1],10);
				
				$array[$id][0] = $id;
				$array[$id][1] = $counter;
			}
		}
		/*plus*/
		$array[$vId][0] = $vId;
		$array[$vId][1] += $num;
		
		foreach ($array as $each){
			$result = $result.$each[0].",".$each[1]." ";
		}
	}
	DEBUGINFO("Exit  UpdateCart, new cart str is ".$result."\r\n");
	return $result;
}

function UpdateSessionToDB($session, $faketime)
{
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);

	$sql = "select * from session where openid='".$session['openid']."'";
	$result = mysql_query($sql);

	if(mysql_num_rows($result) > 0)
	{
		$sql ="update session set status=".$session['status'].",cart='".
			$session['cart']."',sessiontime = '".$faketime."' where openid='".$session['openid']."'";
		$result = mysql_query($sql);
	}
	else
	{
		$sql ="insert into session values ('".$session['openid']."',".$session['status'].",'".
			$session['cart']."','".$faketime."')";
		$result = mysql_query($sql);	
	}
	DEBUGINFO("Update Session, new status is ".$session['status']."!\r\n");
	mysql_close($con);
	return null;
}

function DestroySessionToDB($openid)
{
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);

	$sql = "delete from session where openid='".$openid."'";
	$result = mysql_query($sql);
	
	mysql_close($con);
	return null;
}

function GetSession($name)
{
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);

	$sql = "select * from session where openid='".$name."'";
	$result = mysql_query($sql);

	/*$num = mysql_num_rows($result);*/
	while($row = mysql_fetch_array($result))
	{
		mysql_close($con);
		return $row; /*get one row*/
	}
	
	mysql_close($con);
	return null;
}

function InitSession($open_id, $faketime)
{
	DestroySessionToDB($open_id);
	$session['openid'] = $open_id;
	$session['status'] = 1;
	$session['cart'] = "";
	UpdateSessionToDB($session, $faketime);
	return $session;
}

function DEBUGINFO($abc)
{
	@ $fp = fopen("debug.txt", 'ab');
	fwrite($fp, $abc);
	fclose($fp);
}
		

/*逆序*/
function compare($x, $y){
	if($x[1] == $y[1]){
		return 0;
	}else if($x[1] < $y[1]){
		return 1;
	}else{
		return -1;
	}
}

function CreateOrder($openid, $cart, $faketime)
{
	DEBUGINFO("Entry Create Order: openid is ".$openid.",cart is ".$cart."\r\n");
	/*先计算总价*/
	$menu = GetFullMenu();
	$total = 0;
	
	$array = explode(" ", trim($cart));
	foreach ($array as $index){
		$temp = explode(",", $index);
		$id = intval($temp[0],10);
		$counter = intval($temp[1],10);
		$parsedInfo[$id] += $counter; /*+=是防止输入：102,1 102,1*/
		DEBUGINFO("id is ".$id.",counter is ".$counter."\r\n");
		
		$total += $menu[$id]['price'] * $counter;
	}
	
	/*操作orders数据库*/
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);

	$sql = "insert into orders values(null,'".$openid."',".$total.",'".$faketime."','defaultaddress');";
	$result = mysql_query($sql);
	DEBUGINFO("###mysql access: ".$sql." ###result is ".$result."\r\n");
	
	/*操作orderinfo数据库*/
	$orderid =  mysql_insert_id(); /*获取auto-increment的插入值*/
	foreach($parsedInfo as $menuid=>$amount){
		$sql = "insert into orderinfo values('".$orderid ."',".$menuid.",".$amount.");";
		$result = mysql_query($sql);
		DEBUGINFO("###mysql access: ".$sql." ###result is ".$result."\r\n");
	}
	
	mysql_close($con);
	DEBUGINFO("Exit  Create Order!\r\n");	
}

/*记录每次用户输入信息*/
function WriteMessage($openid, $messagetype, $content, $faketime)
{
	$con = mysql_connect("127.0.0.1","root","redhat");
	if (!$con)
	{
		die('Could not connect: ' . mysql_error());
	}

	mysql_select_db("test", $con);
	mysql_query("set names utf8");

	$sqlsentence = "insert into message values ('".$openid."','text','".$content."','".$faketime."');";
	$result = mysql_query($sqlsentence);
	DEBUGINFO("###mysql access: ".$sqlsentence." ###result is ".$result."\r\n");
	
	mysql_close($con);
}

/*here is entry....*/
$fromUsername = $_GET[from];
$toUsername = $_GET[to];
$content = urldecode(trim($_GET[cont]));  /*delete whitespaces in left and right*/
$faketime = urldecode($_GET[faketime]);

DEBUGINFO("\r\n\r\n\r\n[".date(DATE_ATOM)."]A new message coming!!!\r\n"."fromUsername:".$fromUsername."\r\n");
DEBUGINFO("toUsername:".$toUsername."\r\n");
DEBUGINFO("content:".$content."\r\n");
DEBUGINFO("faketime:".$faketime."\r\n");

if(!isset($faketime) || 0 == strlen($faketime)){
	$faketime = date('Y-m-d H:i:s');
}

if(empty( $content )){
	DEBUGINFO("content is empty...\r\n");
	exit;
}
/*写message数据库*/
WriteMessage($fromUsername, "text", $content, $faketime);

/*老化处理：超过30分钟未更新购物车，老化*/
$session = GetSession($fromUsername);
if(!isset($session)){
	DEBUGINFO("Session: EMPTY, then init session!\r\n");
	$session = InitSession($fromUsername,$faketime);
}else{ /*举例上一次访问*/
	$stamp1 = strtotime($session['sessiontime']);
	$stamp2 = strtotime($faketime); /*注意！由于时间造假老化时间以接受的faketime为准*/
	DEBUGINFO("Session: last session time is ".$session['sessiontime'].", current time is ".$faketime."\r\n");

	if($stamp2-$stamp1 > SESSIONAGING){
		DEBUGINFO("Session: TIMEOUT, then init session! From last access has elaped ".($stamp2-$stamp1)."seconds!\r\n");
		$session = InitSession($fromUsername,$faketime);
	}else{
		DEBUGINFO("Session: ALIVE，then Remain unchanged! Aging time is ".SESSIONAGING." seconds!\r\n");
	}
}

/*state machine*/
DEBUGINFO("State machine: status is ".$session['status']."\r\n");
if(1==$session['status']){
	/*jump to status is 1*/
}else if(2==$session['status']){  /*after input buy*/
	if(eregi('y', $content)||eregi('yes', $content)||ereg('是', $content)){
		CreateOrder($fromUsername, $session['cart'], $faketime);
		$post_msg = AssembleCartMsg($session['cart'], "您的订单已生成！欢迎您继续挑选！", $toUsername, $fromUsername);
		echo $post_msg;
		InitSession($fromUsername,$faketime);
		exit;
	}else{
		$session['status'] = 1;
		UpdateSessionToDB($session,$faketime);
		$post_msg = AssembleTextMsg("订单没有生成！欢迎您继续挑选！", $toUsername, $fromUsername);
		echo $post_msg;
		exit;
	}
}else if(3==$session['status']){ /*after input cancel*/
	if(eregi('y', $content)||eregi('yes', $content)||ereg('是', $content)){
		InitSession($fromUsername,$faketime);
		$post_msg = AssembleTextMsg("订单已取消，清空购物车！欢迎您继续挑选！", $toUsername, $fromUsername);
		echo $post_msg;
		exit;
	}else{
		$session['status'] = 1;
		UpdateSessionToDB($session,$faketime);
		$post_msg = AssembleTextMsg("订单没有取消！请您继续挑选！", $toUsername, $fromUsername);
		echo $post_msg;
		exit;
	}
}

/*status is 1*/
/********************************************help*********************************************/
if(0 == strcmp('?', $content) || 0 == strcmp('？', $content) || 0 == strcmp('帮助', $content)||0 == strcasecmp('help', $content)){
	DEBUGINFO("Go to print help!\r\n");
	$post_msg = AssembleTextMsg($g_helpmsg, $toUsername, $fromUsername);
	echo $post_msg;
	exit;
}
/********************************************bye*********************************************/
if(eregi('^bye$', $content)){
	DEBUGINFO("Go to bye!\r\n");	
	$session = GetSession($fromUsername);
	DestroySessionToDB($fromUsername);
	echo AssembleTextMsg("谢谢惠顾，欢迎再次光临！", $toUsername, $fromUsername);
	exit;
}
/***************************************菜单号********************************************/
/*1、check menu 2、check session or add session 3、add to cart*/
if(eregi('[0-9]+', $content)){
	DEBUGINFO("Go to process digit number!\r\n");
	
	/*check menu*/
	$menu_id = intval($content, 10);
	if(CheckMenuId($menu_id)==0){
		DEBUGINFO("menuid doesnot exit!\r\n");
		$post_msg = AssembleTextMsg("sorry，你要的商品不存在。。", $toUsername, $fromUsername);
		echo $post_msg;
		exit;
	}

	/*get session or add session*/
	$session = GetSession($fromUsername);
	if(!isset($session)){
		InitSession($fromUsername,$faketime);
	}
	
	/*add to cart  and  updata to db*/
	$cart = $session['cart']; /*mind for empty~~~*/
	$session['cart'] = UpdateCart($cart, $menu_id, 1);
	UpdateSessionToDB($session,$faketime);

	$post_msg = AssembleCartMsg($session['cart'], NULL, $toUsername, $fromUsername);
	echo $post_msg;
	exit;
}
/***************************************buy********************************************/
if(eregi('buy', $content)||ereg('购买', $content)){
	DEBUGINFO("Go to process buy!\r\n");
	$session = GetSession($fromUsername);
	if(!isset($session)){
		DEBUGINFO("Not find session!\r\n");
		$post_msg = AssembleTextMsg("您还没有购买任何商品！", $toUsername, $fromUsername);
		echo $post_msg;
		exit;
	}
	
	/*购物车为空*/
	if(0 == strlen(trim($session['cart']))){
		DEBUGINFO("Cart is empty!\r\n");
		$post_msg = AssembleTextMsg("您还没有购买任何商品！", $toUsername, $fromUsername);
		echo $post_msg;
		exit;
	}
	
	$session['status'] = 2;
	UpdateSessionToDB($session,$faketime);
	
	$append = "回复y或yes下单！回复其他则继续挑选！";
	$post_msg = AssembleCartMsg($session['cart'], $append, $toUsername, $fromUsername);
	echo $post_msg;
	exit;
}
/***************************************cancel********************************************/
if(eregi('cancel', $content)||ereg('取消', $content)){
	DEBUGINFO("Go to process cancel!\r\n");
	$session = GetSession($fromUsername);
	if(isset($session) && 0 != strlen(trim($session['cart']))){
		DEBUGINFO("Input cancel: Got to clear cart!\r\n");
		
		$append = "取消购买吗？请输入y或yes确定！";
		$post_msg = AssembleCartMsg($session['cart'], $append, $toUsername, $fromUsername);
		echo $post_msg;
		
		$session['status'] = 3;
		UpdateSessionToDB($session,$faketime);
	}else{
		DEBUGINFO("Input cancel: No need to clear!\r\n");
		$post_msg = AssembleTextMsg("您没有要取消的订单!请继续挑选！", $toUsername, $fromUsername);
		echo $post_msg;
	}

	exit;
}
/***************************************cart********************************************/
if(eregi('cart', $content)|| ereg('购物车', $content)){
	DEBUGINFO("Go to process buy!\r\n");
	$session = GetSession($fromUsername);
	if(isset($session) && 0 != strlen(trim($session['cart']))){
		$post_msg = AssembleCartMsg($session['cart'], NULL, $toUsername, $fromUsername);
	}else{
		$post_msg = AssembleTextMsg("您还没有购买任何商品！", $toUsername, $fromUsername);
	}
	echo $post_msg;
	exit;
}
/***************************************movie********************************************/
if(eregi('movie', $content)|| ereg('视频', $content)){
	/*to be continued....*/
	exit;
}
/***************************************default********************************************/
DEBUGINFO("Go to default processor\r\n");

$session = GetSession($fromUsername);
if(!isset($session)){
	initSession($fromUsername,$faketime);
}

$menu = GetSearchMenu($content);
if(count($menu)<=0){  /*re-search*/
	DEBUGINFO("Go to get full menu!\r\n");
	$menu = GetFullMenu();
}
$post_msg = AssembleMenuMsg($menu, $toUsername, $fromUsername);
echo $post_msg;
exit;

?>